import { ref, computed } from 'vue';
import { useQuasar } from 'quasar';

/**
 * A composable function for generic CRUD operations.
 * @param {object} config - The configuration object.
 * @param {ref} config.initialRows - A ref containing the initial data rows.
 * @param {Function} config.itemFactory - A function that returns a new, empty item object.
 * @param {string} config.itemName - The name of the item for notification messages (e.g., '用户').
 * @param {Function} [config.beforeDelete] - Optional hook before deleting an item. Return false to prevent deletion.
 */
export function useCrud(config) {
  const { initialRows, itemFactory, itemName, beforeDelete } = config;

  const $q = useQuasar();
  const rows = ref([...initialRows]);
  const filter = ref('');

  const dialogVisible = ref(false);
  const isEditMode = ref(false);
  const formData = ref(itemFactory());

  function openAddDialog() {
    isEditMode.value = false;
    formData.value = itemFactory();
    dialogVisible.value = true;
  }

  function openEditDialog(item) {
    isEditMode.value = true;
    formData.value = { ...item };
    dialogVisible.value = true;
  }

  function saveItem() {
    if (isEditMode.value) {
      const index = rows.value.findIndex(r => r.id === formData.value.id);
      if (index !== -1) {
        rows.value[index] = { ...formData.value };
      }
    } else {
      const maxId = rows.value.length > 0 ? Math.max(...rows.value.map(r => r.id)) : 0;
      formData.value.id = maxId + 1;
      // Add creation date if the object has a property for it
      if (Object.prototype.hasOwnProperty.call(itemFactory(), 'registration_date')) {
        formData.value.registration_date = new Date().toISOString();
      }
      if (Object.prototype.hasOwnProperty.call(itemFactory(), 'create_time')) {
        formData.value.create_time = new Date().toISOString();
      }
      rows.value.unshift({ ...formData.value });
    }
    dialogVisible.value = false;
    $q.notify({
      color: 'positive',
      message: `${itemName} ${isEditMode.value ? '更新成功' : '新增成功'}`,
      icon: 'check',
    });
  }

  function confirmDelete(item) {
    if (beforeDelete) {
        const canDelete = beforeDelete(item, rows.value);
        if (!canDelete) return;
    }

    $q.dialog({
      title: '确认删除',
      message: `你确定要删除 “${item.name}” 吗?`,
      cancel: true,
      persistent: true,
    }).onOk(() => {
      const index = rows.value.findIndex(r => r.id === item.id);
      if (index !== -1) {
        rows.value.splice(index, 1);
        $q.notify({
          color: 'positive',
          message: `${itemName} 删除成功`,
          icon: 'check',
        });
      }
    });
  }

  const filteredRows = computed(() => {
    if (!filter.value) {
      return rows.value;
    }
    const lowerCaseFilter = filter.value.toLowerCase();
    return rows.value.filter(row => {
      return Object.values(row).some(val =>
        String(val).toLowerCase().includes(lowerCaseFilter)
      );
    });
  });

  return {
    rows,
    filter,
    dialogVisible,
    isEditMode,
    formData,
    filteredRows,
    openAddDialog,
    openEditDialog,
    saveItem,
    confirmDelete,
  };
}
